# -*- coding: utf-8 -*-

from application import app,db
from common.libs.Helper import getFormatDate,getCurrentDate
from common.models.member.Member import Member
from common.models.pay.PayOrder import PayOrder
from common.models.stat.StatDailyFood import StatDailyFood
from common.models.stat.StatDailySite import StatDailySite
from common.models.stat.StatDailyMember import StatDailyMember
from common.models.food.WxShareHistory import WxShareHistory
from common.models.food.FoodSaleChangeLog import FoodSaleChangeLog
from sqlalchemy import func
import random
'''
python manager.py runjob -m stat/daily -a member|food|site -p 2018-07-01    
'''

# python manager.py runjob -m stat/daily -a member
# python manager.py runjob -m stat/daily -a food -p 2022-02-06

# -p 是跑指定日期的

# -p 跑当天的  也可以state 跑日期的   app.logger.info(parame)  打印 相当于前端的console。log

#可以对月统计,和对日统计
class JobTask():
    def __init__(self):
        pass

    def run(self, params):
        act = params['act'] if 'act' in params else ''
        # 传的是跑日期的参数
        date = params['param'][0] if params['param'] and len(params['param']) else getFormatDate(formate="%Y-%m-%d")   #这是一个list列表
        app.logger.info(params)
        app.logger.info(act)
        app.logger.info(date)
        if not act:
            return

        date_from = date + " 00:00:00"
        date_to = date + " 23:59:59"
        func_params = {
            'act': act,
            'date':date,
            'date_from':date_from,
            'date_to':date_to
        }
        if act == "member":       #跑会员统计
            self.statMember( func_params )
        elif act == "food":   #跑售卖统计
            self.statFood( func_params )
        elif act == "site":  #跑全站统计
            self.statSite( func_params)
        elif act == "test":
            self.test()

        app.logger.info("it's over~~")
        return

    '''
    会员统计
    '''
    def statMember(self,params):
        act = params['act']
        date = params['date']
        date_from = params['date_from']
        date_to = params['date_to']
        app.logger.info( "act:{0},from:{1},to:{2}".format( act,date_from,date_to ) )
        # format()用于格式化方法，即用来控制字符串和变量的显示效果。  中括号里放入的是对应的参数
        member_list = Member.query.all()   #查出member 用户表里的所有信息
        if not member_list:
            app.logger.info( "no member list" )
            return

        for member_info in member_list:
            # 通过时间和 memberid来遍历信息
            tmp_stat_member = StatDailyMember.query.filter_by( date = date,member_id = member_info.id ).first()
            if tmp_stat_member:
                tmp_model_stat_member = tmp_stat_member       #如果存在就接结果集
                #对member_id 进行求模
            else:
                tmp_model_stat_member = StatDailyMember()
                tmp_model_stat_member.date = date
                tmp_model_stat_member.member_id = member_info.id
                tmp_model_stat_member.created_time = getCurrentDate()
            # 统计用户总的支付金额
            tmp_stat_pay =  db.session.query( func.sum(PayOrder.total_price).label("total_pay_money")) \
                    .filter( PayOrder.member_id  == member_info.id ,PayOrder.status == 1 )\
                    .filter( PayOrder.created_time >= date_from,PayOrder.created_time <= date_to ).first()
            #统计总的分享次数   count 进行数量上的计算
            tmp_stat_share_count = WxShareHistory.query.filter( PayOrder.member_id  == member_info.id  )\
                    .filter( PayOrder.created_time >= date_from,PayOrder.created_time <= date_to ).count()
            # fliter是复杂查询 而fliterby是复杂查询
            tmp_model_stat_member.total_shared_count = tmp_stat_share_count
            tmp_model_stat_member.total_pay_money = tmp_stat_pay[ 0 ] if tmp_stat_pay[ 0 ] else 0.00
            '''
            为了测试效果模拟数据  采用radom随机生产的办法进行随机数据的生成
            '''
            tmp_model_stat_member.total_shared_count = random.randint(50,100)
            tmp_model_stat_member.total_pay_money = random.randint(1000,1010)
            tmp_model_stat_member.updated_time = getCurrentDate()
            db.session.add( tmp_model_stat_member )
            db.session.commit()

        return True

    '''
    Food统计   商品的售卖情况的统计 也就是统计销售情况  将food_sale_change_log 食物数据变更表中的数据取出
    '''
    def statFood(self,params):
        act = params['act']
        date = params['date']
        date_from = params['date_from']
        date_to = params['date_to']
        app.logger.info( "act:{0},from:{1},to:{2}".format( act,date_from,date_to ) )
        # db.session.query(Foodid) 进行复杂查询   func.sun 得到总的销售数量  得到总的销售金额
        stat_food_list = db.session.query(FoodSaleChangeLog.food_id, func.sum(FoodSaleChangeLog.quantity).label("total_count"),
                         func.sum(FoodSaleChangeLog.price).label("total_pay_money")).filter(FoodSaleChangeLog.created_time >= date_from, FoodSaleChangeLog.created_time <= date_to)\
            .group_by( FoodSaleChangeLog.food_id ).all()   #商品进行聚合

        if not stat_food_list:
            app.logger.info("no data")
            return

        # 对stat_food_list 里的数据进行循环便利
        for item in stat_food_list:
            tmp_food_id = item[ 0 ]
            tmp_stat_food = StatDailyFood.query.filter_by(date=date, food_id = tmp_food_id ).first()
            if tmp_stat_food:
                tmp_model_stat_food = tmp_stat_food
            else:
                tmp_model_stat_food = StatDailyFood()
                tmp_model_stat_food.date = date
                tmp_model_stat_food.food_id = tmp_food_id
                tmp_model_stat_food.created_time = getCurrentDate()

            tmp_model_stat_food.total_count = item[1]
            tmp_model_stat_food.total_pay_money = item[2]
            tmp_model_stat_food.updated_time = getCurrentDate()

            '''
            为了测试效果模拟数据
            '''
            # tmp_model_stat_food.total_count = random.randint(50, 100)
            # tmp_model_stat_food.total_pay_money = random.randint(1000, 1010)

            db.session.add( tmp_model_stat_food )
            db.session.commit()

        return
    '''
    site统计
    '''
    def statSite(self,params):
        act = params['act']
        date = params['date']
        date_from = params['date_from']
        date_to = params['date_to']
        app.logger.info( "act:{0},from:{1},to:{2}".format( act,date_from,date_to ) )
        # 查询总支付金额在Pay  func.sum 进行总的支付金额的计算  给返回结果起一个别名  total_pay_money  且状态值为1的查出来  并且进行一个时间的判断
        stat_pay = db.session.query(func.sum(PayOrder.total_price).label("total_pay_money")) \
            .filter(PayOrder.status == 1) \
            .filter(PayOrder.created_time >= date_from, PayOrder.created_time <= date_to).first()

        # 统计会员总数 和当日新增的会员总数
        stat_member_count = Member.query.count()  #Member表中所有的数据求和
        stat_new_member_count = Member.query.filter(Member.created_time >= date_from,   #查询条件在24小时之内的数据进行求和
                            Member.created_time <= date_to).count()
        # 订单数量进行统计     状态值是1的 1就是支付完成的订单量进行统计
        stat_order_count = PayOrder.query.filter_by( status = 1 )\
            .filter(PayOrder.created_time >= date_from, PayOrder.created_time <= date_to)\
            .count()
        # 分析总数量 进行计算 当日的
        stat_share_count = WxShareHistory.query.filter(WxShareHistory.created_time >= date_from
            ,WxShareHistory.created_time <= date_to).count()

        # 当天统计如果有一条了的话就进行更新，没有的话就进行插入
        tmp_stat_site = StatDailySite.query.filter_by(date=date).first()
        if tmp_stat_site:
            tmp_model_stat_site = tmp_stat_site
        else:
            # 相关字段进行跟新
            tmp_model_stat_site = StatDailySite()
            tmp_model_stat_site.date = date
            tmp_model_stat_site.created_time = getCurrentDate()

        tmp_model_stat_site.total_pay_money = stat_pay[ 0 ] if stat_pay[ 0 ] else 0.00
        tmp_model_stat_site.total_new_member_count = stat_new_member_count
        tmp_model_stat_site.total_member_count = stat_member_count
        tmp_model_stat_site.total_order_count = stat_order_count
        tmp_model_stat_site.total_shared_count = stat_share_count
        tmp_model_stat_site.updated_time = getCurrentDate()
        '''
        为了测试效果模拟数据
        '''
        tmp_model_stat_site.total_pay_money = random.randint(1000, 1010)
        tmp_model_stat_site.total_new_member_count = random.randint(50, 100)
        tmp_model_stat_site.total_member_count += tmp_model_stat_site.total_new_member_count
        tmp_model_stat_site.total_order_count = random.randint(900, 1000)
        tmp_model_stat_site.total_shared_count = random.randint(1000, 2000)
        db.session.add(tmp_model_stat_site)
        db.session.commit()

    # 做测试数据 让当前时间往前面跑30天
    def test(self):
        import datetime
        from common.libs.Helper import getFormatDate
        now = datetime.datetime.now()   #拿当前的时间
        for i in reversed( range( 1,30 ) ):   #倒叙 1 到30之间的数据进行排列
            date_before =now + datetime.timedelta( days = -i )     #计算30天之前的日期
            print(type(date_before))
            # print(type(format = "%Y-%m-%d" ))
            date = getFormatDate( date = date_before, formate="%Y-%m-%d")
            print(type(date))
            tmp_params = {
                'act': 'test',
                'date': date,
                'date_from': date + " 00:00:00",
                'date_to':  date + " 23:59:59"
            }
            self.testFood( date )
            self.statFood( tmp_params )
            self.statMember( tmp_params )
            self.statSite( tmp_params )

    def testFood(self,date):
        from common.models.food.Food import Food
        list = Food.query.all()
        if list:
            for item in list:
                model =  FoodSaleChangeLog()
                model.food_id =  item.id
                model.quantity =  random.randint( 1,10 )
                model.price = model.quantity * item.price
                model.member_id = 1
                model.created_time = date + " " + getFormatDate( formate = "%H:%M:%S")
                db.session.add( model )
                db.session.commit()
